const express = require('express');
const { exec } = require('child_process');
const bodyParser = require('body-parser');
const officegen = require('officegen');
const fs = require('fs');
const path = require('path');
const archiver = require('archiver');

const analysisFns = require('./analysisFns');

const app = express();
// 限制传参内容大小
app.use(bodyParser.json({ limit: '100mb' }));
app.use(bodyParser.urlencoded({ limit: '100mb', extended: true }));
app.use(express.json());

// 解决跨域问题
app.all('*', (req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  res.header('Access-Control-Allow-Methods', '*');
  res.header('Content-Type', 'application/json;charset=utf-8');
  next();
});

app.listen('8089', () => {
  console.log('系统启动成功');
  // 打开前端页面
  const command =
    process.platform === 'win32' ? 'start front.html' : 'open front.html';
  exec(command, (error) => {
    if (error) {
      console.error(`打开front.html时出错: ${error}`);
      return;
    }
  });
});

app.post('/analysis', async (req, res) => {
  const { inputText: jsonString } = req.body;
  try {
    console.log('👮‍♀️', '开始解析');
    fs.rmSync(
      'temp',
      { recursive: true, force: true, maxRetries: 3, retryDelay: 100 },
      (err) => {
        if (err) {
          console.error('删除缓存文件时出错:', err);
          return;
        }
      }
    );
    fs.mkdir('temp', { recursive: true }, (err) => {
      if (err) {
        console.error('创建缓存文件夹时出错:', err);
        return;
      }
    });
    let json = JSON.parse(jsonString);
    let quesitonsInfos = json.data;
    // 创建两个docx文件：题目和答案
    const docxFileQuestion = officegen({
      type: 'docx',
      pageSize: 'A4',
      orientation: 'portrait',
    });
    const docxFileAnswer = officegen({
      type: 'docx',
      pageSize: 'A4',
      orientation: 'portrait',
    });
    // 进行json解析
    await analysisFns.parseJson(
      docxFileQuestion,
      docxFileAnswer,
      quesitonsInfos
    );
    console.log('🥳', '解析完成');
    // 生成docx文件并压入zip包
    const cwd = process.cwd();
    const archiveZip = archiver('zip', {
      zlib: { level: 9 },
    });
    const relativePathZip = path.join('temp', '生成文件.zip');
    archiveZip.on('finish', () => {
      res.setHeader('Content-Type', 'application/zip');
      res.setHeader(
        'Content-Disposition',
        'attachment; filename="archive.zip"'
      );
      const fileStream = fs.createReadStream(path.join(cwd, relativePathZip));
      fileStream.pipe(res);
    });
    const outputZip = fs.createWriteStream(path.join(cwd, relativePathZip));
    archiveZip.pipe(outputZip);
    let filesAdded = 0;
    const checkAndFinalize = () => {
      filesAdded++;
      if (filesAdded === 2) {
        archiveZip.finalize();
      }
    };
    // 生成题目文件
    const relativePathQuestion = path.join('temp', '题目.docx');
    const outStreamQuestion = fs.createWriteStream(
      path.join(cwd, relativePathQuestion)
    );
    outStreamQuestion.on('finish', () => {
      setTimeout(() => {
        archiveZip.file(path.join(cwd, relativePathQuestion), {
          name: '题目.docx',
        });
        checkAndFinalize();
      }, 5000);
    });
    docxFileQuestion.generate(outStreamQuestion);
    // 生成答案文件
    const relativePathAnswer = path.join('temp', '答案.docx');
    const outStreamAnswer = fs.createWriteStream(
      path.join(cwd, relativePathAnswer)
    );
    outStreamAnswer.on('finish', () => {
      setTimeout(() => {
        archiveZip.file(path.join(cwd, relativePathAnswer), {
          name: '答案.docx',
        });
        checkAndFinalize();
      }, 10000);
    });
    docxFileAnswer.generate(outStreamAnswer);
  } catch (e) {
    console.log('解析JSON失败: ', e);
    res.status(200).json({
      code: 500,
      message: '解析JSON失败',
    });
  }
});
